﻿using System;
using Interfaces;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;

namespace simpel_Server
{
    public class ClientHandler : IDisposable
    {
        private Socket clientSocket;
        private NetworkStream netStream;
        private StreamWriter writer;
        private StreamReader reader;
        private bool _active = true;
        private readonly Responder _responder = Responder.Instance;
        private Server server;
        object _senderLock = new object();


        public ClientHandler(Socket clientSocket, Server server)
        {
            this.server = server;
            this.clientSocket = clientSocket;
        }

        public void RunClient()
        {
            netStream = new NetworkStream(clientSocket);
            writer = new StreamWriter(netStream);
            reader = new StreamReader(netStream);


            doDialog();

            writer.Close();
            reader.Close();
            netStream.Close();
            clientSocket.Shutdown(SocketShutdown.Both);
            clientSocket.Close();
        }

        private void sendToClient(string text)
        {
            lock (_senderLock)
            {
                try
                {
                    writer.WriteLine(text);
                    writer.Flush();
                }
                catch
                {
                    _active = false;
                }
            }


        }

        private string receiveFromClient()
        {
            try
            {
                return reader.ReadLine();
            }
            catch
            {
                _active = false;
                return null;
            }
        }

        private void doDialog()
        {
            while (_active)
                ExecuteCommand();      
        }
        private bool ExecuteCommand()  
        {
            string command = receiveFromClient();
            if (command == null)
            {
                System.Threading.Thread.Sleep(200);
                return false;
            }
            if (command.StartsWith("vis"))
                //beder responderen om at sende "vis" (en liste over auktioner)
                sendToClient(_responder.Vis());
            else if (command.StartsWith("byd"))//byder på en auktion
            {
                IAuktion svar = _responder.Byd(command.Trim().Substring(3));

                if (svar == null)
                {
                    sendToClient("ugyldigt bud");
                }
                else
                {
                    server.TilmeldMeddelse(svar, this);
                    sendToClient("Du har det højeste bud på auktion nr.: " + svar.Nummer);
                }


            }
            else if (command.StartsWith("tilmeld")) //tilmelder sig en konkret auktion
            {
                IAuktion svar = _responder.Tilmeld(command.Trim().Substring(7));

                if (svar == null)
                {
                    sendToClient("ugyldigt tilmelding");
                }
                else
                {
                    server.TilmeldMeddelse(svar, this);
                    sendToClient("Du er tilmeldt på auktion nr.: " + svar.Nummer);
                }
            }
            else
                sendToClient("Ukendt kommando");
            return true;
        }


        internal void SendUpdate(string p)
        {
            sendToClient(p);
        }

        public void Dispose()
        {
            //der er problemer med en proces der bliver hængende efter at programmet burde være afsluttet, så vi prøver lige manuelt
            _active = false;
            try
            {
                writer.Close();
                reader.Close();
                netStream.Close();
                clientSocket.Shutdown(SocketShutdown.Both);
                clientSocket.Close();
            }
            catch 
            {
               
            }
            writer.Dispose();
            reader.Dispose();
            netStream.Dispose();


        }
    }
}


